package com.sika.code.test.server.business.auth.domain.entity.login;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.sika.code.infrastructure.common.base.constant.BaseConstant;
import com.sika.code.infrastructure.common.base.pojo.domain.entity.BaseStandardEntity;
import com.sika.code.test.server.business.auth.constant.LoginCodeEnum;
import com.sika.code.test.server.business.auth.db.repository.AuthRepository;
import com.sika.code.test.server.business.auth.pojo.dto.LoginUserDTO;
import com.sika.code.test.server.business.auth.pojo.request.LoginRequest;
import lombok.Data;
import lombok.experimental.Accessors;

/**
 * <p>
 * 用户登录实体
 * </p>
 *
 * @author daiqi
 * @date 2021/11/8 23:51
 */
@Data
@Accessors(chain = true)
public abstract class LoginEntity extends BaseStandardEntity<LoginUserDTO> {
    protected LoginRequest userLoginRequest;
    protected AuthRepository authRepository;
    protected LoginUserDTO loginUserDTO;

    @Override
    protected void executeBefore() {
        verifyInitBefore();
        init();
        verifyInitAfter();
    }

    @Override
    protected LoginUserDTO doExecute() {
        StpUtil.login(this.loginUserDTO.getId());
        return loginUserDTO;
    }

    protected abstract void verifyInitBefore();

    protected void init() {
        this.loginUserDTO = buildLoginUserDTO();
    }

    protected void verifyInitAfter() {
        verifyLoginUser();
    }

    protected void verifyLoginUser() {
        verifyUserExist();
        verifyUserState();
        verifyLoginCredentials();
    }

    protected void verifyUserExist() {
        Assert.notNull(this.loginUserDTO, "用户不存在");
    }

    protected void verifyUserState() {
        boolean availableFlag = BaseConstant.AvailableEnum.available(this.loginUserDTO.getAvailable());
        Assert.isTrue(availableFlag, "该用户已被冻结，请申请解冻");
    }

    /**
     * 校验登录凭据
     */
    protected abstract void verifyLoginCredentials();

    protected LoginUserDTO buildLoginUserDTO() {
        return authRepository.findLoginUser(userLoginRequest);
    }

    protected void verifyLoginByCode(String key, LoginCodeEnum loginCodeEnum) {
        // 从repository中获取验证码
        String loginCodeFromServer = authRepository.getLoginCodeByKey(key, loginCodeEnum);
        Assert.notBlank(loginCodeFromServer, "验证码已失效，请重新获取验证码");
        // 校验验证码是否一致
        boolean correctCode = StrUtil.equals(userLoginRequest.getLoginKey(), loginCodeFromServer);
        Assert.isTrue(correctCode, "验证码有误，请重新输入");
    }
}
